/*
 * Copyright (C) 2018 Logos Technology Ltd.
 */

package com.logos.common.update;

import android.content.Context;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import java.nio.charset.Charset;

public class UpdateManager {

    private static String sUrl;
    private static String sChannel;
    // 非wifi网络不检查更新
    private static boolean sIsWifiOnly = true;

    /**
     * set wifi
     *
     * @param wifiOnly boolean
     */
    public static void setWifiOnly(boolean wifiOnly) {
        sIsWifiOnly = wifiOnly;
    }

    /**
     * set url
     *
     * @param url     string
     * @param channel string
     */
    public static void setUrl(String url, String channel) {
        sUrl = url;
        sChannel = channel;
    }

    public static void setDebuggable(boolean debuggable) {
        UpdateUtil.sDebug = debuggable;
    }

    /**
     * install
     * @param context Context
     */
    public static void install(Context context) {

        UpdateUtil.install(context, true);
    }

    /**
     * check
     * @param context Context
     */
    public static void check(Context context) {
        create(context).check();
    }

    /**
     * checkManual
     * @param context Context
     */
    public static void checkManual(Context context) {
        create(context).setManual(true).check();
    }

    /**
     * create
     * @param context Context
     * @return Builder
     */
    public static Builder create(Context context) {
        UpdateUtil.ensureExternalCacheDir(context);
        return new Builder(context).setWifiOnly(sIsWifiOnly);
    }

    public static class Builder {
        private Context mContext;
        private String mUrl;
        private byte[] mPostData;
        private boolean mIsManual;
        private boolean mIsWifiOnly;
        private int mNotifyId = 0;

        private OnDownloadListener mOnNotificationDownloadListener;
        private OnDownloadListener mOnDownloadListener;
        private IUpdatePrompter mPrompter;
        private OnFailureListener mOnFailureListener;

        private IUpdateParser mParser;
        private IUpdateChecker mChecker;
        private IUpdateDownloader mDownloader;

        /**
         * set context
         *
         * @param context context
         */
        public Builder(Context context) {
            mContext = context;
        }

        /**
         * set url
         *
         * @param url string
         * @return Builder
         */
        public Builder setUrl(String url) {
            mUrl = url;
            return this;
        }

        /**
         * set post data
         *
         * @param data byte[]
         * @return Builder
         */
        public Builder setPostData(@NonNull byte[] data) {
            mPostData = data;
            return this;
        }

        /**
         * set post data
         *
         * @param data data
         * @return Builder
         */
        public Builder setPostData(@NonNull String data) {
            mPostData = data.getBytes(Charset.forName("UTF-8"));
            return this;
        }

        /**
         * set Notify
         *
         * @param notifyId int
         * @return Builder
         */
        public Builder setNotifyId(int notifyId) {
            mNotifyId = notifyId;
            return this;
        }

        /**
         * set Manual
         *
         * @param isManual boolean
         * @return Builder
         */
        public Builder setManual(boolean isManual) {
            mIsManual = isManual;
            return this;
        }

        /**
         * set wifi
         *
         * @param isWifiOnly boolean
         * @return Builder
         */
        public Builder setWifiOnly(boolean isWifiOnly) {
            mIsWifiOnly = isWifiOnly;
            return this;
        }

        /**
         * set parser
         *
         * @param parser IUpdateParser
         * @return Builder
         */
        public Builder setParser(@NonNull IUpdateParser parser) {
            mParser = parser;
            return this;
        }

        /**
         * set checker
         *
         * @param checker IUpdateChecker
         * @return Builder
         */
        public Builder setChecker(@NonNull IUpdateChecker checker) {
            mChecker = checker;
            return this;
        }

        /**
         * set down loader
         *
         * @param downloader IUpdateDownloader
         * @return Builder
         */
        public Builder setDownloader(@NonNull IUpdateDownloader downloader) {
            mDownloader = downloader;
            return this;
        }

        /**
         * set prompter
         *
         * @param prompter IUpdatePrompter
         * @return Builder
         */
        public Builder setPrompter(@NonNull IUpdatePrompter prompter) {
            mPrompter = prompter;
            return this;
        }

        /**
         * set on notification down load listener
         *
         * @param listener OnDownloadListener
         * @return Builder
         */
        public Builder setOnNotificationDownloadListener(@NonNull OnDownloadListener listener) {
            mOnNotificationDownloadListener = listener;
            return this;
        }

        /**
         * set down load listener
         *
         * @param listener OnDownloadListener
         * @return Builder
         */
        public Builder setOnDownloadListener(@NonNull OnDownloadListener listener) {
            mOnDownloadListener = listener;
            return this;
        }

        /**
         * set on fail listener
         *
         * @param listener OnFailureListener
         * @return Builder
         */
        public Builder setOnFailureListener(@NonNull OnFailureListener listener) {
            mOnFailureListener = listener;
            return this;
        }

        private static long sLastTime;

        /**
         * check
         */
        public void check() {
            long now = System.currentTimeMillis();
            if (now - sLastTime < 500) {
                return;
            }
            sLastTime = now;

            if (TextUtils.isEmpty(mUrl)) {
                mUrl = UpdateUtil.toCheckUrl(mContext, sUrl, sChannel);
            }

            UpdateAgent agent = new UpdateAgent(mContext, mUrl, mIsManual, mIsWifiOnly, mNotifyId);
            if (mOnNotificationDownloadListener != null) {
                agent.setOnNotificationDownloadListener(mOnNotificationDownloadListener);
            }
            if (mOnDownloadListener != null) {
                agent.setOnDownloadListener(mOnDownloadListener);
            }
            if (mOnFailureListener != null) {
                agent.setOnFailureListener(mOnFailureListener);
            }
            if (mChecker != null) {
                agent.setChecker(mChecker);
            } else {
                agent.setChecker(new UpdateChecker(mPostData));
            }
            if (mParser != null) {
                agent.setParser(mParser);
            }
            if (mDownloader != null) {
                agent.setDownloader(mDownloader);
            }
            if (mPrompter != null) {
                agent.setPrompter(mPrompter);
            }
            agent.check();
        }
    }
}
